package src.core;

import java.io.*;
import java.net.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

public class GameServer {
    private static final int PORT = 8888;
    private static final int MAX_PLAYERS = 4;
    private static final int SPEED = 5;
    private static final int BROADCAST_INTERVAL = 50; // 广播间隔(毫秒)

    // 存储玩家信息和客户端输出流
    private static final ConcurrentHashMap<Integer, Player> players = new ConcurrentHashMap<>();
    private static final ConcurrentHashMap<Integer, PrintWriter> clientWriters = new ConcurrentHashMap<>();
    private static final AtomicInteger playerIdCounter = new AtomicInteger(0);
    private static final ScheduledExecutorService broadcastExecutor = Executors.newSingleThreadScheduledExecutor();

    public static void main(String[] args) {
        ExecutorService executor = Executors.newCachedThreadPool();

        // 启动定期广播任务
        broadcastExecutor.scheduleAtFixedRate(
                GameServer::broadcastPositions,
                0, BROADCAST_INTERVAL, TimeUnit.MILLISECONDS);

        try (ServerSocket serverSocket = new ServerSocket(PORT)) {
            System.out.println("游戏服务器已启动，等待玩家连接...");

            while (true) {
                Socket clientSocket = serverSocket.accept();
                if (players.size() >= MAX_PLAYERS) {
                    System.out.println("玩家数量已达上限，拒绝连接");
                    clientSocket.close();
                    continue;
                }

                int playerId = playerIdCounter.incrementAndGet();
                Player newPlayer = new Player(playerId, 100, 100);
                players.put(playerId, newPlayer);

                System.out.println("玩家 " + playerId + " 已连接");

                executor.execute(new ClientHandler(clientSocket, playerId));
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            broadcastExecutor.shutdown();
        }
    }

    // 定期广播所有玩家位置
    private static synchronized void broadcastPositions() {
        String positions = getAllPositions();
        for (PrintWriter writer : clientWriters.values()) {
            try {
                writer.println(positions);
            } catch (Exception e) {
                System.out.println("广播位置信息时出错: " + e.getMessage());
            }
        }
    }

    // 处理玩家移动
    public static synchronized void handleMovement(int playerId, char direction) {
        Player player = players.get(playerId);
        if (player == null) return;

        switch (direction) {
            case 'W':
                player.y -= SPEED;
                break;
            case 'A':
                player.x -= SPEED;
                break;
            case 'S':
                player.y += SPEED;
                break;
            case 'D':
                player.x += SPEED;
                break;
        }

        System.out.printf("玩家 %d 移动到 (%d, %d)\n", playerId, player.x, player.y);
    }

    // 获取所有玩家位置信息
    public static synchronized String getAllPositions() {
        StringBuilder sb = new StringBuilder();
        for (Player player : players.values()) {
            sb.append(player.id).append(",")
                    .append(player.x).append(",")
                    .append(player.y).append(";");
        }
        return sb.toString();
    }

    // 移除断开连接的玩家
    public static synchronized void removePlayer(int playerId) {
        players.remove(playerId);
        clientWriters.remove(playerId);
        System.out.println("玩家 " + playerId + " 已断开连接");
    }

    // 玩家类
    static class Player {
        int id;
        int x;
        int y;

        public Player(int id, int x, int y) {
            this.id = id;
            this.x = x;
            this.y = y;
        }
    }

    // 客户端处理线程
    static class ClientHandler implements Runnable {
        private final Socket socket;
        private final int playerId;
        private BufferedReader in;
        private PrintWriter out;

        public ClientHandler(Socket socket, int playerId) {
            this.socket = socket;
            this.playerId = playerId;
        }

        @Override
        public void run() {
            try {
                in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                out = new PrintWriter(socket.getOutputStream(), true);

                // 保存客户端输出流用于广播
                clientWriters.put(playerId, out);

                // 发送玩家ID
                out.println("ID:" + playerId);

                String inputLine;
                while ((inputLine = in.readLine()) != null) {
                    if (inputLine.length() == 1) {
                        char direction = inputLine.toUpperCase().charAt(0);
                        if ("WASD".indexOf(direction) != -1) {
                            GameServer.handleMovement(playerId, direction);
                        }
                    }
                }
            } catch (IOException e) {
                System.out.println("玩家 " + playerId + " 连接异常: " + e.getMessage());
            } finally {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                GameServer.removePlayer(playerId);
            }
        }
    }
}